/*
 * Copyright 2024 The JA-SIG Collaborative. All rights reserved.
 * distributed with thi file and available online at
 */
package com.lap.permission.service.impl;

import com.lap.framework.enums.YesNo;
import com.lap.permission.convert.Convert;
import com.lap.permission.dal.RegionDAO;
import com.lap.permission.domain.entity.Region;
import com.lap.permission.dto.response.RegionDTO;
import com.lap.permission.service.RegionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.util.*;

@Slf4j
@RequiredArgsConstructor
@Service
public class RegionServiceImpl implements RegionService {
    private final RegionDAO regionDAO;

    private final Convert convert;

    @Override
    public List<RegionDTO> queryTree() {
        List<Region> list = regionDAO.queryList();
        return getTree(list);
    }

    private List<RegionDTO> getTree(List<Region> list) {
        if (CollectionUtils.isEmpty(list))
            return Collections.emptyList();

        List<RegionDTO> sourceList = list.stream()
                .map(convert::toRegionDto)
                .toList();

        List<RegionDTO> result = sourceList.stream()
                .filter(region -> YesNo.NO.getValue().equals(region.getPid()))
                .sorted(Comparator.comparing(RegionDTO::getOrders))
                .toList();

        for (RegionDTO dto : result) {
            getSub(dto, sourceList, 0);
        }
        return result;
    }

    private RegionDTO getSub(RegionDTO parent, List<RegionDTO> sources, int dept) {
        log.debug("dept:::{}", dept);
        ++dept;
        if (dept >= 30)
            return parent;

        for (RegionDTO region : sources) {
            if (parent.getId().equals(region.getPid())) {
                List<RegionDTO> child = parent.getChildren();
                if (Objects.isNull(child)) {
                    child = new LinkedList<>();
                    parent.setChildren(child);
                }
                parent.getChildren().add(getSub(region, sources, dept));
                Collections.sort(parent.getChildren());
            }
        }
        return parent;
    }

    @Override
    public Region queryById(Integer regionId) {
        return regionDAO.queryById(regionId);
    }

    @Override
    public Region queryByName(String name) {
        return regionDAO.queryByName(name);
    }

    @Override
    public List<Region> queryByIds(List<Integer> list) {
        return regionDAO.queryByIds(list);
    }

    @Override
    public RegionDTO queryByPid(Integer pid) {
        Region region = Optional.ofNullable(regionDAO.queryById(pid)).orElse(empty());
        RegionDTO dto = convert.toRegionDto(region);

        List<Region> list = regionDAO.queryByPid(pid);
        dto.setChildren(convert.toRegionDto(list));
        return dto;
    }

    private Region empty() {
        Region region = new Region();
        region.setPid(0);
        return region;
    }

    @Override
    public Integer insertRegion(Region region) {
        regionDAO.insertRegion(region);
        return region.getId();
    }

    @Override
    public int updateRegion(Region region) {
        return regionDAO.updateRegion(region);
    }

    @Override
    public int deleteById(Integer regionId) {
        return regionDAO.deleteById(regionId);
    }

}
